package com.ldy.server;

import com.ldy.service.HelloService;
import com.ldy.service.impl.HelloServiceImpl;
import org.apache.thrift.protocol.  TJSONProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.server.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.transport.layered.TFastFramedTransport;


/**
 * @Auther lin DeYU
 * @Date 2021/3/29
 */
public class HelloThriftServerFactory {

    private int PORT=8080;

    public void setPort(int port){
        this.PORT=port;
    }

    public int getPORT(){
        return this.PORT;
    }

    /**
     * 返回一个TsimpleServer, 采用了阻塞性IO，一次只能接收处理一个客户端socket,也就是说一次只能与一个客户端socket进行通信。
     * @return TSimpleServer
     * @throws TTransportException
     */
    public TSimpleServer getSimpleServer() throws TTransportException {
        // 设置通信端口
        TServerSocket serverSocket=new TServerSocket(this.PORT);
        //远程的访问接口服务,先比较RPC框架dubbo，一个 TServer一个服务端口只能代理一个远程接口，局限性
        HelloService.Processor processor =
                new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl());
        // 采用什么样方式序列化
          TJSONProtocol.Factory protocolFactory = new   TJSONProtocol.Factory();
        // 设置远程服务的参数，ip端口，代理的远程接口，
        TServer.Args targs=new TServer.Args(serverSocket);
        // 设置远程调用的过程
        targs.processor(processor);
        // 传输数据序列化的协议
        targs.protocolFactory(protocolFactory);
        return new TSimpleServer(targs);
    }


    /**
     *  TThreadPoolServer 采用阻塞的socket方式工作，主线程负责阻塞方式监听客户端连接，具体业务交由线程池处理。
     * @return TThreadPoolServer
     * @throws TTransportException
     */

    public TThreadPoolServer getTThreadPoolServer() throws TTransportException {
        // 设置通信端口
        TServerSocket serverSocket=new TServerSocket(this.PORT);
        HelloService.Processor processor =
                new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl());
        // 采用什么序列化
          TJSONProtocol.Factory protocolFactory = new   TJSONProtocol.Factory();
        // 设置 TServer 的参数
        TThreadPoolServer.Args targs=new TThreadPoolServer.Args(serverSocket);
        //设置远程调用的过程
        targs.processor(processor);
        // 传输数据序列化的协议
        targs.protocolFactory(protocolFactory);
        return new TThreadPoolServer(targs);
    }


    /**
     * TNonblockingServer模式也是单线程工作，但是采用NIO的模式，借助Channel/Selector机制, 采用IO事件模型来处理。
     * @return TNonblockingServer
     * @throws TTransportException
     */
    public TNonblockingServer getTNonblockingServer() throws TTransportException {
        // 设置通信监听端口
        TNonblockingServerSocket tNonblockingServerSocket=new TNonblockingServerSocket(PORT);
        HelloService.Processor processor =
                new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl());
        // 数据序列化的方式
          TJSONProtocol.Factory protocolFactory = new   TJSONProtocol.Factory();
        TNonblockingServer.Args targs=new TNonblockingServer.Args(tNonblockingServerSocket);
        //设置远程调用的过程
        targs.processor(processor);
        // 传输数据序列化的协议
        targs.protocolFactory(protocolFactory);
        //设置数据传输的方式
        targs.transportFactory(new TFastFramedTransport.Factory());
        return new TNonblockingServer(targs);
    }


    /**
     * 鉴于TNonblockingServer的缺点，THsHaServer继承于TNonblockingServer，引入了线程池提高了任务处理的并发能力。THsHaServer是半同步半异步(Half-Sync/Half-Async)的处理模式，
     * Half-Aysnc用于IO事件处理(Accept/Read/Write)，Half-Sync用于业务handler对rpc的同步处理上。
     * @return
     * @throws TTransportException
     */
    public THsHaServer getTHsHaServer() throws TTransportException {
        // 设置通信端口
        TNonblockingServerSocket tNonblockingServerSocket=new TNonblockingServerSocket(PORT);
        HelloService.Processor processor =
                new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl());
        // 采用二进制方式进行序列化
          TJSONProtocol.Factory protocolFactory = new   TJSONProtocol.Factory();
        THsHaServer.Args targs=new THsHaServer.Args(tNonblockingServerSocket);
        // 设置远程调用的过程
        targs.processor(processor);
        // 传输数据序列化的协议
        targs.protocolFactory(protocolFactory);
        //设置指定TFramedTransport数据传输的方式
        targs.transportFactory(new TFastFramedTransport.Factory());
        return new THsHaServer(targs);
    }


    /**
     * TThreadedSelectorServer是对THsHaServer的一种扩充，它将selector中的读写IO事件(read/write)从主线程中分离出来。同时引入worker工作线程池，它也是种Half-Sync/Half-Async的服务模型。
     * @return  TThreadedSelectorServer
     * @throws TTransportException
     */
    public TThreadedSelectorServer getTThreadedSelectorServer() throws TTransportException {
        // 设置通信端口
        TNonblockingServerSocket tNonblockingServerSocket=new TNonblockingServerSocket(PORT);
        HelloService.Processor processor =
                new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl());
        // 采用什么样的方式序列化
          TJSONProtocol.Factory protocolFactory = new   TJSONProtocol.Factory();
        TThreadedSelectorServer.Args targs=new TThreadedSelectorServer.Args(tNonblockingServerSocket);
        // 设置远程调用的过程
        targs.processor(processor);
        // 传输数据序列化的协议
        targs.protocolFactory(protocolFactory);
        // 设置数据传输的方式
        targs.transportFactory(new TFastFramedTransport.Factory());
        return new TThreadedSelectorServer(targs);
    }


}

